package com.sirap.fish;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sirap.basic.component.Konstants;
import com.sirap.basic.tool.D;
import com.sirap.basic.util.Amaps;
import com.sirap.basic.util.EmptyUtil;
import com.sirap.basic.util.FileUtil;
import com.sirap.basic.util.IOUtil;
import com.sirap.basic.util.StrUtil;
import com.sirap.basic.util.XXXUtil;

public class FishFileHelper {
	
	public static List<Map<String, Object>> getImageSubFoldersFrom(String dir) {
		List<File> files = FileUtil.getSubFilesByLastModifiedDescend(dir);
		Collections.sort(files, new Comparator<File>() {
			@Override
			public int compare(File f1, File f2) {
				return valueOf(f1).compareTo(valueOf(f2));
			}
			
			private Integer valueOf(File file) {
				if(StrUtil.equals(file.getName(), "upload")) {
					return -1;
				} else {
					return 0;
				}
			}
		});
		
		List<Map<String, Object>> items = Lists.newArrayList();
		for(File file : files) {
			if(!file.isDirectory()) {
				continue;
			}
			
			String[] kids = file.list(new FilenameFilter() {
				@Override
				public boolean accept(File dir, String name) {
					String extension = FileUtil.extensionOf(name);
					D.pla(name, extension);
					boolean isImage = StrUtil.isIn(extension, FileUtil.EXTENSIONS_IMAGE);
					if(isImage) {
						return true;
					}
					boolean isVideo = StrUtil.isIn(extension, FileUtil.EXTENSIONS_VIDEO);
					if(isVideo) {
						return true;
					}
					
					return false;
				}
			});
			
			if(EmptyUtil.isNullOrEmpty(kids)) {
//				continue;
			}
			
			Map<String, Object> props = Amaps.createMap("count", kids.length);
			props.put("name", file.getName());
			long filesize = FileUtil.sizeOf(file.getAbsolutePath());
			props.put("size", FileUtil.formatSize(filesize));
			items.add(props);
		}
		
		return items;
	}
	
	public static List<Map<String, Object>> getNormalFilesFrom(String dir) {
		List<File> files = FileUtil.getSubFilesByLastModifiedDescend(dir);
		final List<Map<String, Object>> holder = Lists.newArrayList();

		int count = 0, next, previous;
		for(File current : files) {
			if(!current.isFile()) {
				continue;
			}
			next = count + 1;
			if(next >= files.size()) {
				next = 0;
			}

			previous = count - 1;
			if(previous < 0) {
				previous = files.size() - 1;
			}
			
			count++;
			
			String path = current.getAbsolutePath();
			String extension = FileUtil.extensionOf(path);
			Map<String, Object> fileitem = Maps.newConcurrentMap();
			fileitem.put("istxt", StrUtil.isIn(extension, FileUtil.EXTENSIONS_TEXT));
			fileitem.put("isimage", StrUtil.isIn(extension, FileUtil.EXTENSIONS_IMAGE));
			fileitem.put("name", current.getName());
			fileitem.put("next", files.get(next).getName());
			fileitem.put("previous", files.get(previous).getName());
			fileitem.put("size", FileUtil.formatSize(current.length()));
			holder.add(fileitem);
		}
		
		return holder;
	}
	
	public static void main(String[] args) {
		D.jsp(FishFileHelper.getBibleBooksByVersion("C:/mastorage/bible/niv"));
	}
	
	public static List<Map<String, Object>> getBibleBooksByVersion(String versionpath) {
		return getBibleBooksByVersion(versionpath, "");
	}
	
	public static List<Map<String, Object>> getBibleBooksByVersion(String versionpath, String bookIdAsCriteria) {
		D.ts(versionpath);
		File mydir = new File(versionpath);
		String dir = mydir.getAbsolutePath();
		List<Map<String, Object>> holder = Lists.newArrayList();

		List<File> bfiles = FileUtil.getSubFilesByNameAscend(dir);
//		D.list(bfiles);
		boolean careChapterpath = !EmptyUtil.isNullOrEmpty(bookIdAsCriteria);
		for(File bfile : bfiles) {
			if(!bfile.isDirectory()) {
				continue;
			}
			
			String bname = bfile.getName();
			String regex = "(\\d{1,2})\\s(.+)";
			String[] params = StrUtil.parseParams(regex, bname);
//			D.pla(params);
			if(params == null) {
				continue;
			}
			
			String bookId = params[0].replaceAll("^[0]+", "");
			if(careChapterpath) {
				if(!StrUtil.equals(bookIdAsCriteria, bookId)) {
					continue;
				}
			}
			String bookName = params[1];
			
			List<String> cids = Lists.newArrayList();
			List<String> cpaths = Lists.newArrayList();
//			D.pla(100, bookId, bookName);
			List<File> cfiles = FileUtil.getSubFilesByNameAscend(bfile.getAbsolutePath());
//			D.list(cfiles);
			for(File cfile : cfiles) {
				if(!cfile.isFile()) {
					continue;
				}
				
				String cname = cfile.getName();
				String chapterId = StrUtil.findFirstMatchedItem("(^\\d{1,3})", cname);
//				D.pla(cname, chapterId);
				if(chapterId == null) {
					continue;
				}
				
				String cid = chapterId.replaceAll("^0+", "");
				cids.add(cid);
//				D.pla(cid, cfile.getAbsolutePath());
				String cpath = cfile.getAbsolutePath().replace(dir, "");
				cpaths.add(cpath);
			}
			
			Map<String, Object> fileitem = Maps.newConcurrentMap();
			fileitem.put("bid", bookId);
			fileitem.put("bname", bookName);
			fileitem.put("cids", cids);
			if(careChapterpath) {
				fileitem.put("cpaths", cpaths);
			}
//			D.pjsp(fileitem);
			holder.add(fileitem);
		}
		
		return holder;
	}
	
	public static List<List<String>> getBibleBooknamesByVersions(String bibleStorage, List<String> versions) {
		List<List<String>> holder = Lists.newArrayList();
		
		for(String version : versions) {
			String versionpath = StrUtil.useSeparator(bibleStorage, version);
			D.ts(versionpath);
			File mydir = new File(versionpath);
			String dir = mydir.getAbsolutePath();
			
			List<File> bfiles = FileUtil.getSubFilesByNameAscend(dir);
			List<String> names = Lists.newArrayList();
			for(File bfile : bfiles) {
				if(!bfile.isDirectory()) {
					continue;
				}
				
				String bname = bfile.getName();
				String regex = "\\d{1,2}\\s(.+)";
				String bookName = StrUtil.parseParam(regex, bname);
				if(bookName == null) {
					continue;
				}
				
				names.add(bookName);
			}
			
			holder.add(names);
		}
		
		return holder;
	}
	
	public static Map<String, Object> getBibleVerses(String bibleStorage, String version, String bookId, String chapterId) {
		D.pla(bookId, chapterId);
		D.pla(bibleStorage, version, bookId, chapterId);
		XXXUtil.shouldBeNotnull(bibleStorage);
		XXXUtil.shouldBeNotnull(version);
		XXXUtil.shouldBeNotnull(bookId);
		XXXUtil.shouldBeNotnull(chapterId);
		String versionpath = StrUtil.useSeparator(bibleStorage, version);
		List<Map<String, Object>> holder = FishFileHelper.getBibleBooksByVersion(versionpath, bookId);
		if(holder.isEmpty()) {
			String msg = "Non-existing chapter {0} with book id {1} in bible storage {2}";
			XXXUtil.alert(msg, bookId, chapterId, versionpath);
		}
		
		Map<String, Object> fileitem = holder.get(0);
		List<String> cids = (List<String>)fileitem.get("cids");
		List<String> cpaths = (List<String>)fileitem.get("cpaths");
		int cdx = cids.indexOf(chapterId);
		if(cdx < 0) {
			String msg = "Non-existing chapter {0} with book id {1} in bible storage {2}";
			XXXUtil.alert(msg, bookId, chapterId, versionpath);
		}
		String cpath = cpaths.get(cdx);
		String fullpath = StrUtil.useSeparator(versionpath, cpath);
		List<String> lines = IOUtil.readLines(fullpath, Konstants.CODE_UTF8);

		fileitem.put("cid", chapterId);
		fileitem.put("lines", lines);
		fileitem.put("version", version);
		
		return fileitem;
	}
}
